@@ -151,6 +151,10 @@ ENABLE_SECOND_PRECISION_SCHEDULE=false |
||
151 | 151 |
# at the expense of time accuracy. |
152 | 152 |
SCHEDULER_FREQUENCY=0.3 |
153 | 153 |
|
154 |
+# Specify the frequency with which the scheduler checks for and cleans up expired events. |
|
155 |
+# You can use `m` for minutes, `h` for hours, and `d` for days. |
|
156 |
+EVENT_EXPIRATION_CHECK=6h |
|
157 |
+ |
|
154 | 158 |
# Use Graphviz for generating diagrams instead of using Google Chart |
155 | 159 |
# Tools. Specify a dot(1) command path built with SVG support |
156 | 160 |
# enabled. |
@@ -21,7 +21,7 @@ class Agent < ActiveRecord::Base |
||
21 | 21 |
SCHEDULES = %w[every_1m every_2m every_5m every_10m every_30m every_1h every_2h every_5h every_12h every_1d every_2d every_7d |
22 | 22 |
midnight 1am 2am 3am 4am 5am 6am 7am 8am 9am 10am 11am noon 1pm 2pm 3pm 4pm 5pm 6pm 7pm 8pm 9pm 10pm 11pm never] |
23 | 23 |
|
24 |
- EVENT_RETENTION_SCHEDULES = [["Forever", 0], ["1 day", 1], *([2, 3, 4, 5, 7, 14, 21, 30, 45, 90, 180, 365].map {|n| ["#{n} days", n] })] |
|
24 |
+ EVENT_RETENTION_SCHEDULES = [["Forever", 0], ['1 hour', 1.hour], ['6 hours', 6.hours], ["1 day", 1.day], *([2, 3, 4, 5, 7, 14, 21, 30, 45, 90, 180, 365].map {|n| ["#{n} days", n.days] })] |
|
25 | 25 |
|
26 | 26 |
attr_accessible :options, :memory, :name, :type, :schedule, :controller_ids, :control_target_ids, :disabled, :source_ids, :scenario_ids, :keep_events_for, :propagate_immediately, :drop_pending_events |
27 | 27 |
|
@@ -130,14 +130,14 @@ class Agent < ActiveRecord::Base |
||
130 | 130 |
end |
131 | 131 |
|
132 | 132 |
def new_event_expiration_date |
133 |
- keep_events_for > 0 ? keep_events_for.days.from_now : nil |
|
133 |
+ keep_events_for > 0 ? keep_events_for.seconds.from_now : nil |
|
134 | 134 |
end |
135 | 135 |
|
136 | 136 |
def update_event_expirations! |
137 | 137 |
if keep_events_for == 0 |
138 | 138 |
events.update_all :expires_at => nil |
139 | 139 |
else |
140 |
- events.update_all "expires_at = " + rdbms_date_add("created_at", "DAY", keep_events_for.to_i) |
|
140 |
+ events.update_all "expires_at = " + rdbms_date_add("created_at", "SECOND", keep_events_for.to_i) |
|
141 | 141 |
end |
142 | 142 |
end |
143 | 143 |
|
@@ -150,7 +150,7 @@ class ScenarioImport |
||
150 | 150 |
def generate_diff |
151 | 151 |
@agent_diffs = (parsed_data['agents'] || []).map.with_index do |agent_data, index| |
152 | 152 |
# AgentDiff is defined at the end of this file. |
153 |
- agent_diff = AgentDiff.new(agent_data) |
|
153 |
+ agent_diff = AgentDiff.new(agent_data, parsed_data['schema_version']) |
|
154 | 154 |
if existing_scenario |
155 | 155 |
# If this Agent exists already, update the AgentDiff with the local version's information. |
156 | 156 |
agent_diff.diff_with! existing_scenario.agents.find_by(:guid => agent_data['guid']) |
@@ -192,14 +192,16 @@ class ScenarioImport |
||
192 | 192 |
end |
193 | 193 |
end |
194 | 194 |
|
195 |
- def initialize(agent_data) |
|
195 |
+ def initialize(agent_data, schema_version) |
|
196 | 196 |
super() |
197 |
+ @schema_version = schema_version |
|
197 | 198 |
@requires_merge = false |
198 | 199 |
self.agent = nil |
199 | 200 |
store! agent_data |
200 | 201 |
end |
201 | 202 |
|
202 | 203 |
BASE_FIELDS = %w[name schedule keep_events_for propagate_immediately disabled guid] |
204 |
+ FIELDS_REQUIRING_TRANSLATION = %w[keep_events_for] |
|
203 | 205 |
|
204 | 206 |
def agent_exists? |
205 | 207 |
!!agent |
@@ -217,10 +219,27 @@ class ScenarioImport |
||
217 | 219 |
self.type = FieldDiff.new(agent_data["type"].split("::").pop) |
218 | 220 |
self.options = FieldDiff.new(agent_data['options'] || {}) |
219 | 221 |
BASE_FIELDS.each do |option| |
220 |
- self[option] = FieldDiff.new(agent_data[option]) if agent_data.has_key?(option) |
|
222 |
+ if agent_data.has_key?(option) |
|
223 |
+ value = agent_data[option] |
|
224 |
+ value = send(:"translate_#{option}", value) if option.in?(FIELDS_REQUIRING_TRANSLATION) |
|
225 |
+ self[option] = FieldDiff.new(value) |
|
226 |
+ end |
|
227 |
+ end |
|
228 |
+ end |
|
229 |
+ |
|
230 |
+ def translate_keep_events_for(old_value) |
|
231 |
+ if schema_version < 1 |
|
232 |
+ # Was stored in days, now is stored in seconds. |
|
233 |
+ old_value.to_i.days |
|
234 |
+ else |
|
235 |
+ old_value |
|
221 | 236 |
end |
222 | 237 |
end |
223 | 238 |
|
239 |
+ def schema_version |
|
240 |
+ (@schema_version || 0).to_i |
|
241 |
+ end |
|
242 |
+ |
|
224 | 243 |
def diff_with!(agent) |
225 | 244 |
return unless agent.present? |
226 | 245 |
|
@@ -14,7 +14,7 @@ |
||
14 | 14 |
<span class='glyphicon glyphicon-warning-sign'></span> |
15 | 15 |
This Scenario already exists in your system. The import will update your existing |
16 | 16 |
<%= scenario_label(@scenario_import.existing_scenario) %> Scenario's title, |
17 |
- description and tag colors. Below you can customize how the individual agents get updated. |
|
17 |
+ description, and tag colors. Below you can customize how the individual agents get updated. |
|
18 | 18 |
</div> |
19 | 19 |
<% end %> |
20 | 20 |
|
@@ -0,0 +1,13 @@ |
||
1 |
+class UpdateKeepEventsForToBeInSeconds < ActiveRecord::Migration |
|
2 |
+ class Agent < ActiveRecord::Base; end |
|
3 |
+ |
|
4 |
+ SECONDS_IN_DAY = 60 * 60 * 24 |
|
5 |
+ |
|
6 |
+ def up |
|
7 |
+ Agent.update_all ['keep_events_for = keep_events_for * ?', SECONDS_IN_DAY] |
|
8 |
+ end |
|
9 |
+ |
|
10 |
+ def down |
|
11 |
+ Agent.update_all ['keep_events_for = keep_events_for / ?', SECONDS_IN_DAY] |
|
12 |
+ end |
|
13 |
+end |
@@ -11,39 +11,39 @@ |
||
11 | 11 |
# |
12 | 12 |
# It's strongly recommended that you check this file into your version control system. |
13 | 13 |
|
14 |
-ActiveRecord::Schema.define(version: 20140906030139) do |
|
15 |
- |
|
16 |
- create_table "agent_logs", force: true do |t| |
|
17 |
- t.integer "agent_id", null: false |
|
18 |
- t.text "message", null: false, charset: "utf8mb4", collation: "utf8mb4_bin" |
|
19 |
- t.integer "level", default: 3, null: false |
|
20 |
- t.integer "inbound_event_id" |
|
21 |
- t.integer "outbound_event_id" |
|
14 |
+ActiveRecord::Schema.define(version: 20150507153436) do |
|
15 |
+ |
|
16 |
+ create_table "agent_logs", force: :cascade do |t| |
|
17 |
+ t.integer "agent_id", limit: 4, null: false |
|
18 |
+ t.text "message", limit: 65535, null: false, charset: "utf8mb4", collation: "utf8mb4_bin" |
|
19 |
+ t.integer "level", limit: 4, default: 3, null: false |
|
20 |
+ t.integer "inbound_event_id", limit: 4 |
|
21 |
+ t.integer "outbound_event_id", limit: 4 |
|
22 | 22 |
t.datetime "created_at" |
23 | 23 |
t.datetime "updated_at" |
24 | 24 |
end |
25 | 25 |
|
26 |
- create_table "agents", force: true do |t| |
|
27 |
- t.integer "user_id" |
|
28 |
- t.text "options", charset: "utf8mb4", collation: "utf8mb4_bin" |
|
29 |
- t.string "type", collation: "utf8_bin" |
|
30 |
- t.string "name", charset: "utf8mb4", collation: "utf8mb4_bin" |
|
31 |
- t.string "schedule", collation: "utf8_bin" |
|
32 |
- t.integer "events_count", default: 0, null: false |
|
26 |
+ create_table "agents", force: :cascade do |t| |
|
27 |
+ t.integer "user_id", limit: 4 |
|
28 |
+ t.text "options", limit: 65535, charset: "utf8mb4", collation: "utf8mb4_bin" |
|
29 |
+ t.string "type", limit: 255, collation: "utf8_bin" |
|
30 |
+ t.string "name", limit: 255, charset: "utf8mb4", collation: "utf8mb4_bin" |
|
31 |
+ t.string "schedule", limit: 255, collation: "utf8_bin" |
|
32 |
+ t.integer "events_count", limit: 4, default: 0, null: false |
|
33 | 33 |
t.datetime "last_check_at" |
34 | 34 |
t.datetime "last_receive_at" |
35 |
- t.integer "last_checked_event_id" |
|
35 |
+ t.integer "last_checked_event_id", limit: 4 |
|
36 | 36 |
t.datetime "created_at" |
37 | 37 |
t.datetime "updated_at" |
38 |
- t.text "memory", limit: 2147483647, charset: "utf8mb4", collation: "utf8mb4_bin" |
|
38 |
+ t.text "memory", limit: 4294967295, charset: "utf8mb4", collation: "utf8mb4_bin" |
|
39 | 39 |
t.datetime "last_web_request_at" |
40 |
- t.integer "keep_events_for", default: 0, null: false |
|
40 |
+ t.integer "keep_events_for", limit: 4, default: 0, null: false |
|
41 | 41 |
t.datetime "last_event_at" |
42 | 42 |
t.datetime "last_error_log_at" |
43 |
- t.boolean "propagate_immediately", default: false, null: false |
|
44 |
- t.boolean "disabled", default: false, null: false |
|
45 |
- t.integer "service_id" |
|
46 |
- t.string "guid", null: false |
|
43 |
+ t.boolean "propagate_immediately", limit: 1, default: false, null: false |
|
44 |
+ t.boolean "disabled", limit: 1, default: false, null: false |
|
45 |
+ t.string "guid", limit: 255, null: false, charset: "ascii", collation: "ascii_bin" |
|
46 |
+ t.integer "service_id", limit: 4 |
|
47 | 47 |
end |
48 | 48 |
|
49 | 49 |
add_index "agents", ["guid"], name: "index_agents_on_guid", using: :btree |
@@ -51,9 +51,9 @@ ActiveRecord::Schema.define(version: 20140906030139) do |
||
51 | 51 |
add_index "agents", ["type"], name: "index_agents_on_type", using: :btree |
52 | 52 |
add_index "agents", ["user_id", "created_at"], name: "index_agents_on_user_id_and_created_at", using: :btree |
53 | 53 |
|
54 |
- create_table "control_links", force: true do |t| |
|
55 |
- t.integer "controller_id", null: false |
|
56 |
- t.integer "control_target_id", null: false |
|
54 |
+ create_table "control_links", force: :cascade do |t| |
|
55 |
+ t.integer "controller_id", limit: 4, null: false |
|
56 |
+ t.integer "control_target_id", limit: 4, null: false |
|
57 | 57 |
t.datetime "created_at" |
58 | 58 |
t.datetime "updated_at" |
59 | 59 |
end |
@@ -61,25 +61,25 @@ ActiveRecord::Schema.define(version: 20140906030139) do |
||
61 | 61 |
add_index "control_links", ["control_target_id"], name: "index_control_links_on_control_target_id", using: :btree |
62 | 62 |
add_index "control_links", ["controller_id", "control_target_id"], name: "index_control_links_on_controller_id_and_control_target_id", unique: true, using: :btree |
63 | 63 |
|
64 |
- create_table "delayed_jobs", force: true do |t| |
|
65 |
- t.integer "priority", default: 0 |
|
66 |
- t.integer "attempts", default: 0 |
|
64 |
+ create_table "delayed_jobs", force: :cascade do |t| |
|
65 |
+ t.integer "priority", limit: 4, default: 0 |
|
66 |
+ t.integer "attempts", limit: 4, default: 0 |
|
67 | 67 |
t.text "handler", limit: 16777215, charset: "utf8mb4", collation: "utf8mb4_bin" |
68 |
- t.text "last_error", charset: "utf8mb4", collation: "utf8mb4_bin" |
|
68 |
+ t.text "last_error", limit: 65535, charset: "utf8mb4", collation: "utf8mb4_bin" |
|
69 | 69 |
t.datetime "run_at" |
70 | 70 |
t.datetime "locked_at" |
71 | 71 |
t.datetime "failed_at" |
72 |
- t.string "locked_by" |
|
73 |
- t.string "queue" |
|
72 |
+ t.string "locked_by", limit: 255 |
|
73 |
+ t.string "queue", limit: 255 |
|
74 | 74 |
t.datetime "created_at" |
75 | 75 |
t.datetime "updated_at" |
76 | 76 |
end |
77 | 77 |
|
78 | 78 |
add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree |
79 | 79 |
|
80 |
- create_table "events", force: true do |t| |
|
81 |
- t.integer "user_id" |
|
82 |
- t.integer "agent_id" |
|
80 |
+ create_table "events", force: :cascade do |t| |
|
81 |
+ t.integer "user_id", limit: 4 |
|
82 |
+ t.integer "agent_id", limit: 4 |
|
83 | 83 |
t.decimal "lat", precision: 15, scale: 10 |
84 | 84 |
t.decimal "lng", precision: 15, scale: 10 |
85 | 85 |
t.text "payload", limit: 16777215, charset: "utf8mb4", collation: "utf8mb4_bin" |
@@ -92,20 +92,20 @@ ActiveRecord::Schema.define(version: 20140906030139) do |
||
92 | 92 |
add_index "events", ["expires_at"], name: "index_events_on_expires_at", using: :btree |
93 | 93 |
add_index "events", ["user_id", "created_at"], name: "index_events_on_user_id_and_created_at", using: :btree |
94 | 94 |
|
95 |
- create_table "links", force: true do |t| |
|
96 |
- t.integer "source_id" |
|
97 |
- t.integer "receiver_id" |
|
95 |
+ create_table "links", force: :cascade do |t| |
|
96 |
+ t.integer "source_id", limit: 4 |
|
97 |
+ t.integer "receiver_id", limit: 4 |
|
98 | 98 |
t.datetime "created_at" |
99 | 99 |
t.datetime "updated_at" |
100 |
- t.integer "event_id_at_creation", default: 0, null: false |
|
100 |
+ t.integer "event_id_at_creation", limit: 4, default: 0, null: false |
|
101 | 101 |
end |
102 | 102 |
|
103 | 103 |
add_index "links", ["receiver_id", "source_id"], name: "index_links_on_receiver_id_and_source_id", using: :btree |
104 | 104 |
add_index "links", ["source_id", "receiver_id"], name: "index_links_on_source_id_and_receiver_id", using: :btree |
105 | 105 |
|
106 |
- create_table "scenario_memberships", force: true do |t| |
|
107 |
- t.integer "agent_id", null: false |
|
108 |
- t.integer "scenario_id", null: false |
|
106 |
+ create_table "scenario_memberships", force: :cascade do |t| |
|
107 |
+ t.integer "agent_id", limit: 4, null: false |
|
108 |
+ t.integer "scenario_id", limit: 4, null: false |
|
109 | 109 |
t.datetime "created_at" |
110 | 110 |
t.datetime "updated_at" |
111 | 111 |
end |
@@ -113,71 +113,71 @@ ActiveRecord::Schema.define(version: 20140906030139) do |
||
113 | 113 |
add_index "scenario_memberships", ["agent_id"], name: "index_scenario_memberships_on_agent_id", using: :btree |
114 | 114 |
add_index "scenario_memberships", ["scenario_id"], name: "index_scenario_memberships_on_scenario_id", using: :btree |
115 | 115 |
|
116 |
- create_table "scenarios", force: true do |t| |
|
117 |
- t.string "name", null: false, charset: "utf8mb4", collation: "utf8mb4_bin" |
|
118 |
- t.integer "user_id", null: false |
|
116 |
+ create_table "scenarios", force: :cascade do |t| |
|
117 |
+ t.string "name", limit: 255, null: false, charset: "utf8mb4", collation: "utf8mb4_bin" |
|
118 |
+ t.integer "user_id", limit: 4, null: false |
|
119 | 119 |
t.datetime "created_at" |
120 | 120 |
t.datetime "updated_at" |
121 |
- t.text "description", charset: "utf8mb4", collation: "utf8mb4_bin" |
|
122 |
- t.boolean "public", default: false, null: false |
|
123 |
- t.string "guid", null: false, charset: "ascii", collation: "ascii_bin" |
|
124 |
- t.string "source_url" |
|
125 |
- t.string "tag_bg_color" |
|
126 |
- t.string "tag_fg_color" |
|
121 |
+ t.text "description", limit: 65535, charset: "utf8mb4", collation: "utf8mb4_bin" |
|
122 |
+ t.boolean "public", limit: 1, default: false, null: false |
|
123 |
+ t.string "guid", limit: 255, null: false, charset: "ascii", collation: "ascii_bin" |
|
124 |
+ t.string "source_url", limit: 255 |
|
125 |
+ t.string "tag_bg_color", limit: 255 |
|
126 |
+ t.string "tag_fg_color", limit: 255 |
|
127 | 127 |
end |
128 | 128 |
|
129 | 129 |
add_index "scenarios", ["user_id", "guid"], name: "index_scenarios_on_user_id_and_guid", unique: true, using: :btree |
130 | 130 |
|
131 |
- create_table "services", force: true do |t| |
|
132 |
- t.integer "user_id", null: false |
|
133 |
- t.string "provider", null: false |
|
134 |
- t.string "name", null: false |
|
135 |
- t.text "token", null: false |
|
136 |
- t.text "secret" |
|
137 |
- t.text "refresh_token" |
|
131 |
+ create_table "services", force: :cascade do |t| |
|
132 |
+ t.integer "user_id", limit: 4, null: false |
|
133 |
+ t.string "provider", limit: 255, null: false, collation: "utf8_general_ci" |
|
134 |
+ t.string "name", limit: 255, null: false, collation: "utf8_general_ci" |
|
135 |
+ t.text "token", limit: 65535, null: false, collation: "utf8_general_ci" |
|
136 |
+ t.text "secret", limit: 65535, collation: "utf8_general_ci" |
|
137 |
+ t.text "refresh_token", limit: 65535, collation: "utf8_general_ci" |
|
138 | 138 |
t.datetime "expires_at" |
139 |
- t.boolean "global", default: false |
|
140 |
- t.text "options" |
|
139 |
+ t.boolean "global", limit: 1, default: false |
|
140 |
+ t.text "options", limit: 65535, collation: "utf8_general_ci" |
|
141 | 141 |
t.datetime "created_at" |
142 | 142 |
t.datetime "updated_at" |
143 |
- t.string "uid" |
|
143 |
+ t.string "uid", limit: 255, collation: "utf8_general_ci" |
|
144 | 144 |
end |
145 | 145 |
|
146 | 146 |
add_index "services", ["provider"], name: "index_services_on_provider", using: :btree |
147 | 147 |
add_index "services", ["uid"], name: "index_services_on_uid", using: :btree |
148 | 148 |
add_index "services", ["user_id", "global"], name: "index_services_on_user_id_and_global", using: :btree |
149 | 149 |
|
150 |
- create_table "user_credentials", force: true do |t| |
|
151 |
- t.integer "user_id", null: false |
|
152 |
- t.string "credential_name", null: false |
|
153 |
- t.text "credential_value", null: false |
|
150 |
+ create_table "user_credentials", force: :cascade do |t| |
|
151 |
+ t.integer "user_id", limit: 4, null: false |
|
152 |
+ t.string "credential_name", limit: 255, null: false |
|
153 |
+ t.text "credential_value", limit: 65535, null: false |
|
154 | 154 |
t.datetime "created_at" |
155 | 155 |
t.datetime "updated_at" |
156 |
- t.string "mode", default: "text", null: false, collation: "utf8_bin" |
|
156 |
+ t.string "mode", limit: 255, default: "text", null: false, collation: "utf8_bin" |
|
157 | 157 |
end |
158 | 158 |
|
159 | 159 |
add_index "user_credentials", ["user_id", "credential_name"], name: "index_user_credentials_on_user_id_and_credential_name", unique: true, using: :btree |
160 | 160 |
|
161 |
- create_table "users", force: true do |t| |
|
162 |
- t.string "email", default: "", null: false, collation: "utf8_bin" |
|
163 |
- t.string "encrypted_password", default: "", null: false, charset: "ascii", collation: "ascii_bin" |
|
164 |
- t.string "reset_password_token", collation: "utf8_bin" |
|
161 |
+ create_table "users", force: :cascade do |t| |
|
162 |
+ t.string "email", limit: 255, default: "", null: false, collation: "utf8_bin" |
|
163 |
+ t.string "encrypted_password", limit: 255, default: "", null: false, charset: "ascii", collation: "ascii_bin" |
|
164 |
+ t.string "reset_password_token", limit: 255, collation: "utf8_bin" |
|
165 | 165 |
t.datetime "reset_password_sent_at" |
166 | 166 |
t.datetime "remember_created_at" |
167 |
- t.integer "sign_in_count", default: 0 |
|
167 |
+ t.integer "sign_in_count", limit: 4, default: 0 |
|
168 | 168 |
t.datetime "current_sign_in_at" |
169 | 169 |
t.datetime "last_sign_in_at" |
170 |
- t.string "current_sign_in_ip" |
|
171 |
- t.string "last_sign_in_ip" |
|
170 |
+ t.string "current_sign_in_ip", limit: 255 |
|
171 |
+ t.string "last_sign_in_ip", limit: 255 |
|
172 | 172 |
t.datetime "created_at" |
173 | 173 |
t.datetime "updated_at" |
174 |
- t.boolean "admin", default: false, null: false |
|
175 |
- t.integer "failed_attempts", default: 0 |
|
176 |
- t.string "unlock_token" |
|
174 |
+ t.boolean "admin", limit: 1, default: false, null: false |
|
175 |
+ t.integer "failed_attempts", limit: 4, default: 0 |
|
176 |
+ t.string "unlock_token", limit: 255 |
|
177 | 177 |
t.datetime "locked_at" |
178 | 178 |
t.string "username", limit: 191, null: false, charset: "utf8mb4", collation: "utf8mb4_unicode_ci" |
179 |
- t.string "invitation_code", null: false, collation: "utf8_bin" |
|
180 |
- t.integer "scenario_count", default: 0, null: false |
|
179 |
+ t.string "invitation_code", limit: 255, null: false, collation: "utf8_bin" |
|
180 |
+ t.integer "scenario_count", limit: 4, default: 0, null: false |
|
181 | 181 |
end |
182 | 182 |
|
183 | 183 |
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree |
@@ -17,11 +17,6 @@ Thread.new do |
||
17 | 17 |
|
18 | 18 |
sleep 45 |
19 | 19 |
|
20 |
- if ENV['DOMAIN'] |
|
21 |
- force_ssl = ENV['FORCE_SSL'] == 'true' |
|
22 |
- Net::HTTP.get_response(URI((force_ssl ? "https://" : "http://") + ENV['DOMAIN'])) |
|
23 |
- end |
|
24 |
- |
|
25 | 20 |
begin |
26 | 21 |
Process.getpgid worker_pid |
27 | 22 |
rescue Errno::ESRCH |
@@ -12,6 +12,7 @@ class AgentsExporter |
||
12 | 12 |
|
13 | 13 |
def as_json(opts = {}) |
14 | 14 |
{ |
15 |
+ :schema_version => 1, |
|
15 | 16 |
:name => options[:name].presence || 'No name provided', |
16 | 17 |
:description => options[:description].presence || 'No description provided', |
17 | 18 |
:source_url => options[:source_url], |
@@ -114,7 +114,7 @@ class HuginnScheduler |
||
114 | 114 |
end |
115 | 115 |
|
116 | 116 |
# Schedule event cleanup. |
117 |
- @rufus_scheduler.cron "0 0 * * * " + tzinfo_friendly_timezone do |
|
117 |
+ @rufus_scheduler.every ENV['EVENT_EXPIRATION_CHECK'].presence || '6h' do |
|
118 | 118 |
cleanup_expired_events! |
119 | 119 |
end |
120 | 120 |
|
@@ -38,7 +38,7 @@ bob_weather_agent: |
||
38 | 38 |
schedule: "midnight" |
39 | 39 |
name: "SF Weather" |
40 | 40 |
guid: <%= SecureRandom.hex %> |
41 |
- keep_events_for: 45 |
|
41 |
+ keep_events_for: <%= 45.days %> |
|
42 | 42 |
options: <%= { :location => 94102, :lat => 37.779329, :lng => -122.41915, :api_key => 'test' }.to_json.inspect %> |
43 | 43 |
|
44 | 44 |
jane_weather_agent: |
@@ -47,7 +47,7 @@ jane_weather_agent: |
||
47 | 47 |
schedule: "midnight" |
48 | 48 |
name: "SF Weather" |
49 | 49 |
guid: <%= SecureRandom.hex %> |
50 |
- keep_events_for: 30 |
|
50 |
+ keep_events_for: <%= 30.days %> |
|
51 | 51 |
options: <%= { :location => 94103, :lat => 37.779329, :lng => -122.41915, :api_key => 'test' }.to_json.inspect %> |
52 | 52 |
|
53 | 53 |
jane_rain_notifier_agent: |
@@ -21,6 +21,7 @@ describe AgentsExporter do |
||
21 | 21 |
expect(data[:description]).to eq(description) |
22 | 22 |
expect(data[:source_url]).to eq(source_url) |
23 | 23 |
expect(data[:guid]).to eq(guid) |
24 |
+ expect(data[:schema_version]).to eq(1) |
|
24 | 25 |
expect(data[:tag_fg_color]).to eq(tag_fg_color) |
25 | 26 |
expect(data[:tag_bg_color]).to eq(tag_bg_color) |
26 | 27 |
expect(Time.parse(data[:exported_at])).to be_within(2).of(Time.now.utc) |
@@ -546,11 +546,11 @@ describe Agent do |
||
546 | 546 |
expect(agent).to have(1).errors_on(:keep_events_for) |
547 | 547 |
agent.keep_events_for = "" |
548 | 548 |
expect(agent).to have(1).errors_on(:keep_events_for) |
549 |
- agent.keep_events_for = 5 |
|
549 |
+ agent.keep_events_for = 5.days.to_i |
|
550 | 550 |
expect(agent).to be_valid |
551 | 551 |
agent.keep_events_for = 0 |
552 | 552 |
expect(agent).to be_valid |
553 |
- agent.keep_events_for = 365 |
|
553 |
+ agent.keep_events_for = 365.days.to_i |
|
554 | 554 |
expect(agent).to be_valid |
555 | 555 |
|
556 | 556 |
# Rails seems to call to_i on the input. This guards against future changes to that behavior. |
@@ -564,7 +564,7 @@ describe Agent do |
||
564 | 564 |
@time = "2014-01-01 01:00:00 +00:00" |
565 | 565 |
time_travel_to @time do |
566 | 566 |
@agent = Agents::SomethingSource.new(:name => "something") |
567 |
- @agent.keep_events_for = 5 |
|
567 |
+ @agent.keep_events_for = 5.days |
|
568 | 568 |
@agent.user = users(:bob) |
569 | 569 |
@agent.save! |
570 | 570 |
@event = @agent.create_event :payload => { "hello" => "world" } |
@@ -580,7 +580,7 @@ describe Agent do |
||
580 | 580 |
@agent.save! |
581 | 581 |
|
582 | 582 |
@agent.options[:foo] = "bar1" |
583 |
- @agent.keep_events_for = 5 |
|
583 |
+ @agent.keep_events_for = 5.days |
|
584 | 584 |
@agent.save! |
585 | 585 |
end |
586 | 586 |
end |
@@ -590,7 +590,7 @@ describe Agent do |
||
590 | 590 |
time_travel_to @time do |
591 | 591 |
expect { |
592 | 592 |
@agent.options[:foo] = "bar1" |
593 |
- @agent.keep_events_for = 3 |
|
593 |
+ @agent.keep_events_for = 3.days |
|
594 | 594 |
@agent.save! |
595 | 595 |
}.to change { @event.reload.expires_at } |
596 | 596 |
expect(@event.expires_at.to_i).to be_within(2).of(3.days.from_now.to_i) |
@@ -603,7 +603,7 @@ describe Agent do |
||
603 | 603 |
|
604 | 604 |
expect { |
605 | 605 |
@agent.options[:foo] = "bar2" |
606 |
- @agent.keep_events_for = 3 |
|
606 |
+ @agent.keep_events_for = 3.days |
|
607 | 607 |
@agent.save! |
608 | 608 |
}.to change { @event.reload.expires_at } |
609 | 609 |
expect(@event.expires_at.to_i).to be_within(60 * 61).of(1.days.from_now.to_i) # The larger time is to deal with daylight savings |
@@ -635,7 +635,7 @@ describe Agent do |
||
635 | 635 |
@receiver = Agents::CannotBeScheduled.new( |
636 | 636 |
name: 'Agent', |
637 | 637 |
options: { foo: 'bar3' }, |
638 |
- keep_events_for: 3, |
|
638 |
+ keep_events_for: 3.days, |
|
639 | 639 |
propagate_immediately: true) |
640 | 640 |
@receiver.user = users(:bob) |
641 | 641 |
@receiver.sources << @sender |
@@ -747,7 +747,7 @@ describe Agent do |
||
747 | 747 |
|
748 | 748 |
it "sets expires_at on created events" do |
749 | 749 |
event = agents(:jane_weather_agent).create_event :payload => { 'hi' => 'there' } |
750 |
- expect(event.expires_at.to_i).to be_within(5).of(agents(:jane_weather_agent).keep_events_for.days.from_now.to_i) |
|
750 |
+ expect(event.expires_at.to_i).to be_within(5).of(agents(:jane_weather_agent).keep_events_for.seconds.from_now.to_i) |
|
751 | 751 |
end |
752 | 752 |
end |
753 | 753 |
|
@@ -836,7 +836,7 @@ describe AgentDrop do |
||
836 | 836 |
}, |
837 | 837 |
}, |
838 | 838 |
schedule: 'every_1h', |
839 |
- keep_events_for: 2) |
|
839 |
+ keep_events_for: 2.days) |
|
840 | 840 |
@wsa1.user = users(:bob) |
841 | 841 |
@wsa1.save! |
842 | 842 |
|
@@ -853,7 +853,7 @@ describe AgentDrop do |
||
853 | 853 |
}, |
854 | 854 |
}, |
855 | 855 |
schedule: 'every_12h', |
856 |
- keep_events_for: 2) |
|
856 |
+ keep_events_for: 2.days) |
|
857 | 857 |
@wsa2.user = users(:bob) |
858 | 858 |
@wsa2.save! |
859 | 859 |
|
@@ -868,7 +868,7 @@ describe AgentDrop do |
||
868 | 868 |
matchers: [], |
869 | 869 |
skip_created_at: 'false', |
870 | 870 |
}, |
871 |
- keep_events_for: 2, |
|
871 |
+ keep_events_for: 2.days, |
|
872 | 872 |
propagate_immediately: true) |
873 | 873 |
@efa.user = users(:bob) |
874 | 874 |
@efa.sources << @wsa1 << @wsa2 |
@@ -9,7 +9,7 @@ describe Agents::FtpsiteAgent do |
||
9 | 9 |
'url' => "ftp://ftp.example.org/pub/releases/", |
10 | 10 |
'patterns' => ["example*.tar.gz"], |
11 | 11 |
} |
12 |
- @checker = Agents::FtpsiteAgent.new(:name => "Example", :options => @site, :keep_events_for => 2) |
|
12 |
+ @checker = Agents::FtpsiteAgent.new(:name => "Example", :options => @site, :keep_events_for => 2.days) |
|
13 | 13 |
@checker.user = users(:bob) |
14 | 14 |
@checker.save! |
15 | 15 |
end |
@@ -14,7 +14,7 @@ describe Agents::ImapFolderAgent do |
||
14 | 14 |
'conditions' => { |
15 | 15 |
} |
16 | 16 |
} |
17 |
- @checker = Agents::ImapFolderAgent.new(:name => 'Example', :options => @site, :keep_events_for => 2) |
|
17 |
+ @checker = Agents::ImapFolderAgent.new(:name => 'Example', :options => @site, :keep_events_for => 2.days) |
|
18 | 18 |
@checker.user = users(:bob) |
19 | 19 |
@checker.save! |
20 | 20 |
|
@@ -20,7 +20,7 @@ describe Agents::WebsiteAgent do |
||
20 | 20 |
'hovertext' => { 'css' => "#comic img", 'value' => "@title" } |
21 | 21 |
} |
22 | 22 |
} |
23 |
- @checker = Agents::WebsiteAgent.new(:name => "xkcd", :options => @valid_options, :keep_events_for => 2) |
|
23 |
+ @checker = Agents::WebsiteAgent.new(:name => "xkcd", :options => @valid_options, :keep_events_for => 2.days) |
|
24 | 24 |
@checker.user = users(:bob) |
25 | 25 |
@checker.save! |
26 | 26 |
end |
@@ -386,7 +386,7 @@ describe Agents::WebsiteAgent do |
||
386 | 386 |
'url' => { 'xpath' => '/feed/entry', 'value' => './link[1]/@href' }, |
387 | 387 |
'thumbnail' => { 'xpath' => '/feed/entry', 'value' => './thumbnail/@url' }, |
388 | 388 |
} |
389 |
- }, keep_events_for: 2) |
|
389 |
+ }, keep_events_for: 2.days) |
|
390 | 390 |
@checker.user = users(:bob) |
391 | 391 |
@checker.save! |
392 | 392 |
end |
@@ -30,7 +30,7 @@ describe ScenarioImport do |
||
30 | 30 |
:type => "Agents::WeatherAgent", |
31 | 31 |
:name => "a weather agent", |
32 | 32 |
:schedule => "5pm", |
33 |
- :keep_events_for => 14, |
|
33 |
+ :keep_events_for => 14.days, |
|
34 | 34 |
:disabled => true, |
35 | 35 |
:guid => "a-weather-agent", |
36 | 36 |
:options => weather_agent_options |
@@ -61,6 +61,7 @@ describe ScenarioImport do |
||
61 | 61 |
end |
62 | 62 |
let(:valid_parsed_data) do |
63 | 63 |
{ |
64 |
+ :schema_version => 1, |
|
64 | 65 |
:name => name, |
65 | 66 |
:description => description, |
66 | 67 |
:guid => guid, |
@@ -204,7 +205,7 @@ describe ScenarioImport do |
||
204 | 205 |
|
205 | 206 |
expect(weather_agent.name).to eq("a weather agent") |
206 | 207 |
expect(weather_agent.schedule).to eq("5pm") |
207 |
- expect(weather_agent.keep_events_for).to eq(14) |
|
208 |
+ expect(weather_agent.keep_events_for).to eq(14.days) |
|
208 | 209 |
expect(weather_agent.propagate_immediately).to be_falsey |
209 | 210 |
expect(weather_agent).to be_disabled |
210 | 211 |
expect(weather_agent.memory).to be_empty |
@@ -228,6 +229,23 @@ describe ScenarioImport do |
||
228 | 229 |
}.to change { users(:bob).agents.count }.by(2) |
229 | 230 |
end |
230 | 231 |
|
232 |
+ context "when the schema_version is less than 1" do |
|
233 |
+ before do |
|
234 |
+ valid_parsed_weather_agent_data[:keep_events_for] = 2 |
|
235 |
+ valid_parsed_data.delete(:schema_version) |
|
236 |
+ end |
|
237 |
+ |
|
238 |
+ it "translates keep_events_for from days to seconds" do |
|
239 |
+ scenario_import.import |
|
240 |
+ expect(scenario_import.errors).to be_empty |
|
241 |
+ weather_agent = scenario_import.scenario.agents.find_by(:guid => "a-weather-agent") |
|
242 |
+ trigger_agent = scenario_import.scenario.agents.find_by(:guid => "a-trigger-agent") |
|
243 |
+ |
|
244 |
+ expect(weather_agent.keep_events_for).to eq(2.days) |
|
245 |
+ expect(trigger_agent.keep_events_for).to eq(0) |
|
246 |
+ end |
|
247 |
+ end |
|
248 |
+ |
|
231 | 249 |
describe "with control links" do |
232 | 250 |
it 'creates the links' do |
233 | 251 |
valid_parsed_data[:control_links] = [ |
@@ -342,7 +360,7 @@ describe ScenarioImport do |
||
342 | 360 |
|
343 | 361 |
expect(weather_agent.name).to eq("a weather agent") |
344 | 362 |
expect(weather_agent.schedule).to eq("5pm") |
345 |
- expect(weather_agent.keep_events_for).to eq(14) |
|
363 |
+ expect(weather_agent.keep_events_for).to eq(14.days) |
|
346 | 364 |
expect(weather_agent.propagate_immediately).to be_falsey |
347 | 365 |
expect(weather_agent).to be_disabled |
348 | 366 |
expect(weather_agent.memory).to be_empty |
@@ -363,7 +381,7 @@ describe ScenarioImport do |
||
363 | 381 |
"0" => { |
364 | 382 |
"name" => "updated name", |
365 | 383 |
"schedule" => "6pm", |
366 |
- "keep_events_for" => "2", |
|
384 |
+ "keep_events_for" => 2.days.to_i.to_s, |
|
367 | 385 |
"disabled" => "false", |
368 | 386 |
"options" => weather_agent_options.merge("api_key" => "foo").to_json |
369 | 387 |
} |
@@ -376,7 +394,7 @@ describe ScenarioImport do |
||
376 | 394 |
weather_agent = existing_scenario.agents.find_by(:guid => "a-weather-agent") |
377 | 395 |
expect(weather_agent.name).to eq("updated name") |
378 | 396 |
expect(weather_agent.schedule).to eq("6pm") |
379 |
- expect(weather_agent.keep_events_for).to eq(2) |
|
397 |
+ expect(weather_agent.keep_events_for).to eq(2.days.to_i) |
|
380 | 398 |
expect(weather_agent).not_to be_disabled |
381 | 399 |
expect(weather_agent.options).to eq(weather_agent_options.merge("api_key" => "foo")) |
382 | 400 |
end |
@@ -386,7 +404,7 @@ describe ScenarioImport do |
||
386 | 404 |
"0" => { |
387 | 405 |
"name" => "", |
388 | 406 |
"schedule" => "foo", |
389 |
- "keep_events_for" => "2", |
|
407 |
+ "keep_events_for" => 2.days.to_i.to_s, |
|
390 | 408 |
"options" => weather_agent_options.merge("api_key" => "").to_json |
391 | 409 |
} |
392 | 410 |
} |
@@ -419,12 +437,40 @@ describe ScenarioImport do |
||
419 | 437 |
end |
420 | 438 |
end |
421 | 439 |
|
440 |
+ context "when the schema_version is less than 1" do |
|
441 |
+ it "translates keep_events_for from days to seconds" do |
|
442 |
+ valid_parsed_data.delete(:schema_version) |
|
443 |
+ valid_parsed_data[:agents] = [valid_parsed_weather_agent_data.merge(keep_events_for: 5)] |
|
444 |
+ |
|
445 |
+ scenario_import.merges = { |
|
446 |
+ "0" => { |
|
447 |
+ "name" => "a new name", |
|
448 |
+ "schedule" => "6pm", |
|
449 |
+ "keep_events_for" => 2.days.to_i.to_s, |
|
450 |
+ "disabled" => "true", |
|
451 |
+ "options" => weather_agent_options.merge("api_key" => "foo").to_json |
|
452 |
+ } |
|
453 |
+ } |
|
454 |
+ |
|
455 |
+ expect(scenario_import).to be_valid |
|
456 |
+ |
|
457 |
+ weather_agent_diff = scenario_import.agent_diffs[0] |
|
458 |
+ |
|
459 |
+ expect(weather_agent_diff.name.current).to eq(agents(:bob_weather_agent).name) |
|
460 |
+ expect(weather_agent_diff.name.incoming).to eq('a weather agent') |
|
461 |
+ expect(weather_agent_diff.name.updated).to eq('a new name') |
|
462 |
+ expect(weather_agent_diff.keep_events_for.current).to eq(45.days.to_i) |
|
463 |
+ expect(weather_agent_diff.keep_events_for.incoming).to eq(5.days.to_i) |
|
464 |
+ expect(weather_agent_diff.keep_events_for.updated).to eq(2.days.to_i.to_s) |
|
465 |
+ end |
|
466 |
+ end |
|
467 |
+ |
|
422 | 468 |
it "sets the 'updated' FieldDiff values based on any feedback from the user" do |
423 | 469 |
scenario_import.merges = { |
424 | 470 |
"0" => { |
425 | 471 |
"name" => "a new name", |
426 | 472 |
"schedule" => "6pm", |
427 |
- "keep_events_for" => "2", |
|
473 |
+ "keep_events_for" => 2.days.to_s, |
|
428 | 474 |
"disabled" => "true", |
429 | 475 |
"options" => weather_agent_options.merge("api_key" => "foo").to_json |
430 | 476 |
}, |
@@ -444,7 +490,8 @@ describe ScenarioImport do |
||
444 | 490 |
expect(weather_agent_diff.name.updated).to eq("a new name") |
445 | 491 |
|
446 | 492 |
expect(weather_agent_diff.schedule.updated).to eq("6pm") |
447 |
- expect(weather_agent_diff.keep_events_for.updated).to eq("2") |
|
493 |
+ expect(weather_agent_diff.keep_events_for.current).to eq(45.days) |
|
494 |
+ expect(weather_agent_diff.keep_events_for.updated).to eq(2.days.to_s) |
|
448 | 495 |
expect(weather_agent_diff.disabled.updated).to eq("true") |
449 | 496 |
expect(weather_agent_diff.options.updated).to eq(weather_agent_options.merge("api_key" => "foo")) |
450 | 497 |
end |